package com.lowcodeai.auth.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.BCrypt;
import com.lowcodeai.auth.dto.LoginRequest;
import com.lowcodeai.auth.dto.LoginResponse;
import com.lowcodeai.auth.entity.UserInfo;
import com.lowcodeai.auth.mapper.UserInfoMapper;
import com.lowcodeai.auth.service.AuthService;
import com.lowcodeai.auth.util.JwtUtil;
import com.lowcodeai.common.result.Result;
import com.lowcodeai.common.result.ResultCode;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 认证服务实现类
 * 
 * @author LowCodeAI
 * @since 1.0.0
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class AuthServiceImpl implements AuthService {

    private final UserInfoMapper userInfoMapper;
    private final StringRedisTemplate redisTemplate;
    private final JwtUtil jwtUtil;

    @Override
    public Result<LoginResponse> login(LoginRequest request) {
        try {
            // 1. 验证用户名密码
            UserInfo userInfo = userInfoMapper.selectByUsername(request.getUsername());
            if (userInfo == null) {
                return Result.error("用户名或密码错误");
            }

            if (userInfo.getStatus() != 1) {
                return Result.error("用户已被禁用");
            }

            if (!BCrypt.checkpw(request.getPassword(), userInfo.getPassword())) {
                return Result.error("用户名或密码错误");
            }

            // 2. 生成Token
            String token = jwtUtil.generateToken(userInfo);
            String refreshToken = jwtUtil.generateRefreshToken(userInfo);

            // 3. 获取用户权限
            List<String> permissions = userInfoMapper.selectPermissionCodesByUserId(userInfo.getId());

            // 4. 构建响应
            LoginResponse response = new LoginResponse();
            response.setToken(token);
            response.setRefreshToken(refreshToken);
            response.setExpiresIn(jwtUtil.getExpirationTime());

            LoginResponse.UserInfo user = new LoginResponse.UserInfo();
            user.setId(userInfo.getId());
            user.setUsername(userInfo.getUsername());
            user.setNickname(userInfo.getNickname());
            user.setEmail(userInfo.getEmail());
            user.setPhone(userInfo.getPhone());
            user.setAvatar(userInfo.getAvatar());
            user.setTenantId(userInfo.getTenantId());
            response.setUserInfo(user);
            response.setPermissions(permissions);

            // 5. 存储Token到Redis
            String redisKey = "token:" + userInfo.getId();
            redisTemplate.opsForValue().set(redisKey, token, jwtUtil.getExpirationTime(), TimeUnit.SECONDS);

            log.info("用户登录成功: {}", userInfo.getUsername());
            return Result.success(response);

        } catch (Exception e) {
            log.error("用户登录失败", e);
            return Result.error("登录失败，请稍后重试");
        }
    }

    @Override
    public Result<Void> logout(String token) {
        try {
            if (StrUtil.isBlank(token)) {
                return Result.error("Token不能为空");
            }

            // 从Token中获取用户ID
            Long userId = jwtUtil.getUserIdFromToken(token);
            if (userId != null) {
                // 从Redis中删除Token
                String redisKey = "token:" + userId;
                redisTemplate.delete(redisKey);
            }

            log.info("用户登出成功");
            return Result.success();

        } catch (Exception e) {
            log.error("用户登出失败", e);
            return Result.error("登出失败");
        }
    }

    @Override
    public Result<LoginResponse> refreshToken(String refreshToken) {
        try {
            if (StrUtil.isBlank(refreshToken)) {
                return Result.error("RefreshToken不能为空");
            }

            // 验证RefreshToken
            if (!jwtUtil.validateRefreshToken(refreshToken)) {
                return Result.error("RefreshToken无效");
            }

            // 从RefreshToken中获取用户信息
            Long userId = jwtUtil.getUserIdFromRefreshToken(refreshToken);
            UserInfo userInfo = userInfoMapper.selectById(userId);
            if (userInfo == null || userInfo.getStatus() != 1) {
                return Result.error("用户不存在或已被禁用");
            }

            // 生成新的Token
            String newToken = jwtUtil.generateToken(userInfo);
            String newRefreshToken = jwtUtil.generateRefreshToken(userInfo);

            // 获取用户权限
            List<String> permissions = userInfoMapper.selectPermissionCodesByUserId(userInfo.getId());

            // 构建响应
            LoginResponse response = new LoginResponse();
            response.setToken(newToken);
            response.setRefreshToken(newRefreshToken);
            response.setExpiresIn(jwtUtil.getExpirationTime());

            LoginResponse.UserInfo user = new LoginResponse.UserInfo();
            user.setId(userInfo.getId());
            user.setUsername(userInfo.getUsername());
            user.setNickname(userInfo.getNickname());
            user.setEmail(userInfo.getEmail());
            user.setPhone(userInfo.getPhone());
            user.setAvatar(userInfo.getAvatar());
            user.setTenantId(userInfo.getTenantId());
            response.setUserInfo(user);
            response.setPermissions(permissions);

            // 更新Redis中的Token
            String redisKey = "token:" + userInfo.getId();
            redisTemplate.opsForValue().set(redisKey, newToken, jwtUtil.getExpirationTime(), TimeUnit.SECONDS);

            return Result.success(response);

        } catch (Exception e) {
            log.error("刷新Token失败", e);
            return Result.error("刷新Token失败");
        }
    }

    @Override
    public Result<LoginResponse.UserInfo> getCurrentUser(String token) {
        try {
            if (StrUtil.isBlank(token)) {
                return Result.error("Token不能为空");
            }

            // 验证Token
            if (!validateToken(token)) {
                return Result.error("Token无效");
            }

            // 从Token中获取用户ID
            Long userId = jwtUtil.getUserIdFromToken(token);
            UserInfo userInfo = userInfoMapper.selectById(userId);
            if (userInfo == null || userInfo.getStatus() != 1) {
                return Result.error("用户不存在或已被禁用");
            }

            // 构建用户信息
            LoginResponse.UserInfo user = new LoginResponse.UserInfo();
            user.setId(userInfo.getId());
            user.setUsername(userInfo.getUsername());
            user.setNickname(userInfo.getNickname());
            user.setEmail(userInfo.getEmail());
            user.setPhone(userInfo.getPhone());
            user.setAvatar(userInfo.getAvatar());
            user.setTenantId(userInfo.getTenantId());

            return Result.success(user);

        } catch (Exception e) {
            log.error("获取当前用户信息失败", e);
            return Result.error("获取用户信息失败");
        }
    }

    @Override
    public boolean validateToken(String token) {
        try {
            if (StrUtil.isBlank(token)) {
                return false;
            }

            // 验证Token格式
            if (!jwtUtil.validateToken(token)) {
                return false;
            }

            // 检查Token是否在Redis中存在
            Long userId = jwtUtil.getUserIdFromToken(token);
            if (userId == null) {
                return false;
            }

            String redisKey = "token:" + userId;
            String storedToken = redisTemplate.opsForValue().get(redisKey);
            return token.equals(storedToken);

        } catch (Exception e) {
            log.error("验证Token失败", e);
            return false;
        }
    }
} 